/*
 * Copyright (c) 2025 Huawei Technologies Co., Ltd.
 * openUBMC is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *         http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

#include <gtest/gtest.h>
#include <test_utilities/test_base.h>
#include <mc/engine.h>
#include <mc/common.h>
#include <thread>
#include <chrono>
#include <atomic>
#include "../../../../drivers/debounce/continue/continue.h"

namespace drivers {
namespace debounce {
namespace continue_test {

class continue_test_service : public mc::engine::service {
public:
    continue_test_service(const std::string& name) : mc::engine::service(name) {}
};

class ContinueTest : public mc::test::TestWithEngine {
protected:
    static void SetUpTestSuite() {
        TestWithEngine::SetUpTestSuite();
        m_test_service = mc::make_shared<continue_test_service>("bmc.kepler.test_continue");
        m_test_service->init();
        m_test_service->start();
    }

    static void TearDownTestSuite() {
        if (m_test_service) {
            m_test_service->stop();
            m_test_service.reset();
        }
        TestWithEngine::TearDownTestSuite();
    }

    void SetUp() override {
        // 确保之前的对象已清理
        if (m_continue) {
            try {
                // 使用对象路径注销对象（路径必须以 '/' 开头）
                std::string path = std::string(m_continue->get_object_path());
                if (!path.empty() && path[0] == '/') {
                    m_test_service->unregister_object(path);
                }
            } catch (...) {
                // 忽略注销失败的情况
            }
            m_continue.reset();
        }
        
        // 等待一下，确保清理完成
        std::this_thread::sleep_for(std::chrono::milliseconds(10));

        // 创建Continue对象，使用唯一的对象名称（基于时间戳和计数器）
        static std::atomic<int> test_counter{0};
        int counter = test_counter.fetch_add(1);
        auto now = std::chrono::steady_clock::now();
        auto timestamp = std::chrono::duration_cast<std::chrono::microseconds>(now.time_since_epoch()).count();
        std::string unique_name = "test_continue_" + std::to_string(timestamp) + "_" + std::to_string(counter);
        
        m_continue = mc::make_shared<dev::Continue>();
        m_continue->set_service(m_test_service.get());
        m_continue->set_object_name(unique_name);
        m_test_service->register_object(m_continue);
    }

    void TearDown() override {
        if (m_continue) {
            try {
                // 使用对象路径注销对象（路径必须以 '/' 开头）
                std::string path = std::string(m_continue->get_object_path());
                if (!path.empty() && path[0] == '/') {
                    m_test_service->unregister_object(path);
                }
            } catch (...) {
                // 忽略注销失败的情况
            }
            m_continue.reset();
        }
    }

    mc::mutable_dict create_test_csr() {
        mc::mutable_dict csr;
        // 根据IContinue接口的实际字段填充
        // 这里假设有一些基本字段
        return csr;
    }

    static mc::shared_ptr<continue_test_service> m_test_service;
    mc::shared_ptr<dev::Continue> m_continue;
};

mc::shared_ptr<continue_test_service> ContinueTest::m_test_service;

// ========================= 基本功能测试 =========================

TEST_F(ContinueTest, Constructor) {
    dev::Continue cont;
    EXPECT_TRUE(true);
}

TEST_F(ContinueTest, Init_Success) {
    auto csr = create_test_csr();
    
    bool result = m_continue->init(csr);
    EXPECT_TRUE(result);
}

TEST_F(ContinueTest, Init_EmptyCsr) {
    mc::mutable_dict empty_csr;
    
    bool result = m_continue->init(empty_csr);
    EXPECT_TRUE(result); // Continue的init总是返回true
}

TEST_F(ContinueTest, FromVariant) {
    mc::mutable_dict csr;
    csr["TestField"] = std::string("test_value");
    
    // 测试from_variant方法
    dev::Continue cont;
    dev::Continue::from_variant(csr, cont);
    
    EXPECT_TRUE(true);
}

// ========================= 多实例测试 =========================

TEST_F(ContinueTest, MultiInstance) {
    std::vector<mc::shared_ptr<dev::Continue>> continues;
    
    for (int i = 0; i < 3; ++i) {
        auto cont = mc::make_shared<dev::Continue>();
        cont->set_service(m_test_service.get());
        cont->set_object_name("test_continue_" + std::to_string(i));
        m_test_service->register_object(cont);
        
        auto csr = create_test_csr();
        bool result = cont->init(csr);
        EXPECT_TRUE(result);
        
        continues.push_back(cont);
    }
    
    // 清理
    for (auto& cont : continues) {
        m_test_service->unregister_object(cont);
    }
}

} // namespace continue_test
} // namespace debounce
} // namespace drivers

